<template>
  <div v-loading="Loading" class="echarts" element-loading-text="数据更新中...">
    <div id="echarts"></div>
  </div>
</template>
<script>
import {
  get_detail,
  executor_sql
} from "@/api/board/datasource.js";
import { _debounce } from '@/utils/utils.js'
import echarts from 'echarts';
export default {
  props: ['data'],
  data() {
    return {
      SQLData: {
        dataMapList: []
      },
      titleList: {
        fieldList: []
      },
      Loading: false,
      curChart: '',
      colors: ['#58D5FF', '#73ACFF', '#FDD56A', '#FDB36A', '#FD866A', '#9E87FF']
    }
  },
  watch: {
    data: {
      handler() {
        this.Loading = true
        if (this.data.graphicalCss && this.data.dataField.Xdata.data && this.data.dataField.Ydata.length !== 0 && this.data.dataField.Ydata[0].data) {
          this.init()
          return
        }
      },
      deep: true,
      immediate: true,
    }
  },
  destroyed() {
    if (this.curChart) {
      this.curChart.clear();
      this.curChart.dispose();
    }
  },
  methods: {
    init: _debounce(function () {
      if (this.curChart) {
        this.curChart.clear();
        this.curChart.dispose();
      }
      this.getData()
    }, 200),
    async  getData() {
      let _this = this
      await get_detail({ id: _this.data.sourceId }).then(res => {
        _this.titleList = res.data
      })
      let data = {
        executeSql: _this.data.executeSql,
        limitCount: _this.titleList.limitCount
      }
      if (_this.data.executeSql) {
        await executor_sql(data).then((res) => {
          _this.SQLData = res.data
        })
      }

      _this.Loading = false
      _this.$nextTick(function () {
        _this.curChart = echarts.init(document.getElementById('echarts'));
        _this.curChart.setOption(_this.getChartOptions(_this.data.graphicalCss, _this.data.dataField.Xdata, _this.data.dataField.Ydata, _this.data.title, _this.SQLData, _this.data.colorCss))
        window.onresize = function () {
          _this.curChart.resize()
        }
      })
    },
    /**
       * 获取图表的配置
       * @param {string} graphicalCss 图样类型
        * @param  {object} xData  x轴的数据
       * @param  {array} yData  y轴的数据
       *   [
       *       {
           *       data: '',
           *        name: ''
           *   }
       *   ]
       * @param  {string} title  标题
       * @param  {array} colors 颜色数组
       * @param {string} SQLData 执行的SQL语句后的数据
       * @return {object}        返回配置对象
       */
    getChartOptions(graphicalCss, xData, yData, title, SQLData, colors) {
      console.log('样式', graphicalCss)
      console.log('title', title)
      console.log('colors', colors)
      console.log('SQLData', SQLData)
      let x = SQLData.dataMapList.map(res => (res[xData.data]))
      let y = yData.map(item => (
        SQLData.dataMapList.map(res => (res[item.data]))
      ))
      console.log('X', JSON.parse(JSON.stringify(x)))
      console.log(' y', JSON.parse(JSON.stringify(y)))
      let option = {
        title: {
          text: `{a|${title}}`,
          textStyle: {
            rich: {
              a: {
                fontWeight: 'bold',
                fontSize: '20',
              },
            }
          },
          left: 'center',
        },
        tooltip: {
          trigger: 'axis',
          backgroundColor: 'rgba(0,15,78,0.6)',
          borderColor: '#00afff',
          borderWidth: 1,
          borderRadius: 0,
          textStyle: {
            color: "#fff",
            fontSize: 13,
            align: 'left'
          },
          axisPointer: {
            type: 'shadow'
          }
        },
        grid: {
          left: '10%',
          right: '10%',
          top: 80,
          bottom: 40,
        },
        legend: {
          type: 'plain',
          left: 0,
          top: 30,
          itemGap: 20,
          itemWidth: 35,
          itemHeight: 20
        },
        dataZoom: [{
          type: 'inside',
          star: '0',
          end: '100'
        }],
        xAxis: {
          name: xData.name,
          nameTextStyle: {
            color: '#000',
            padding: [0, 0, 0, 20]

          },
          data: x,
          show: true,
          type: 'category',
          axisLine: {
            show: true,
            lineStyle: {
              color: 'rgba(0,0,0,0.8)',
              shadowOffsetX: '20',
            },
            symbol: ['none', 'arrow'],
            symbolOffset: [0, 25]
          },
          axisLabel: {
            rotate: -30,
            fontSize: 12,
            color: '#000',
          },
        },
        yAxis: {
          show: true,
          splitNumber: 8,
          axisLine: {
            show: true,
            lineStyle: {
              color: 'rgba(0,0,0,0.8)'
            },
          },
          splitLine: {
            show: true,
            lineStyle: {
              color: 'rgba(0,0,0,0.3)'
            },
          },
          axisLabel: {
            color: '#000',
          }
        },
        series: []
      }
      /**柱状图（簇状柱）*/
      if (graphicalCss == 'bar-basic') {
        option.series = y.map((item, index) => {
          let obj = {
            z: index,
            name: yData[index].name,
            type: 'bar',
            barMaxWidth: '40',
            barMinWidth: '20',
            barGap: '8%',
            barCategoryGap: '20%',
            itemStyle: {
              normal: {
                color: colors[index]
              }
            },
            data: item
          }
          return obj
        })
      }
      /**柱状图（堆积柱）*/
      if (graphicalCss == 'bar-stack') {
        option.series = y.map((item, index) => {
          let obj = {
            z: index,
            name: yData[index].name,
            type: 'bar',
            barMaxWidth: '40',
            barMinWidth: '20',
            barCategoryGap: '20%',
            barGap: '-100%',
            itemStyle: {
              normal: {
                color: colors[index]
              }
            },
            data: item
          }
          return obj
        })
      }
      /**条形图*/
      if (graphicalCss == 'bar-y') {
        option.dataZoom = []
        option.series = y.map((item, index) => {
          let obj = {
            z: index,
            name: yData[index].name,
            type: 'bar',
            barMaxWidth: '20',
            barMinWidth: '10',
            barGap: '8%',
            barCategoryGap: '20%',
            itemStyle: {
              normal: {
                color: colors[index]
              }
            },
            data: item
          }
          return obj
        })
        option.xAxis = {
          name: xData.name,
          nameTextStyle: {
            color: '#000',
            padding: [0, 0, 0, 20]

          },
          splitNumber: 8,
          show: true,
          type: 'value',
          axisLine: {
            show: true,
            lineStyle: {
              color: 'rgba(0,0,0,0.8)',
              shadowOffsetX: '20',
            },
            symbol: ['none', 'arrow'],
            symbolOffset: [0, 25]
          },
          axisLabel: {
            rotate: -30,
            fontSize: 12,
            color: '#000',
          },
        }
        option.yAxis = {
          type: 'category',
          axisLabel: {
            rotate: -30,
            fontSize: 12,
            color: '#000',
          },
          data: x,
        }
        // option.dataZoom = [
        //   {
        //     type: 'slider',
        //     show: true,
        //     yAxisIndex: [0],
        //     start: 1,
        //     end: 35
        //   },
        // ]
      }
      /**折线图*/
      if (graphicalCss == 'line-basic') {
        option.series = y.map((item, index) => {
          let obj = {
            z: index,
            name: yData[index].name,
            type: 'line',
            symbol: 'circle',
            itemStyle: {
              normal: {
                color: colors[index]
              }
            },
            data: item
          }
          return obj
        })
        option.tooltip.axisPointer = {
          type: 'line',
          lineStyle: {
            width: 1,
            type: 'dotted',
            color: 'rgba(46,149,230,.9)'
          }
        }
      }
      /**饼状图（饼状）*/
      if (graphicalCss == 'pie-basic') {
        let ciecle = x.map((item, index) => {
          let obj = {
            name: item,
            value: y[0][index]
          }
          return obj
        })
        option = {
          title: {
            text: `{a|${title}}`,
            textStyle: {
              rich: {
                a: {
                  fontWeight: 'bold',
                  fontSize: '20',
                },
              }
            },
            left: 'center',
          },
          tooltip: {
            trigger: 'axis',
            axisPointer: {
              type: 'shadow'
            }
          },
        }
        option.series = [
          {
            type: 'pie',
            center: ['50%', '50%'],
            radius: ['0%', '50%'],
            minAngle: 10,
            avoidLabelOverlap: true,
            hoverOffset: 15,
            itemStyle: {
              borderColor: '#fff',
              borderWidth: 4,
              color: (params) => {
                return colors[params.dataIndex % colors.length]
              }
            },
            label: {
              show: true,
              position: 'outer',
              alignTo: 'labelLine',
              // ·圆点
              backgroundColor: 'auto', //圆点颜色，auto：映射的系列色
              height: 0,
              width: 0,
              lineHeight: 0,
              // height,width.lineHeight必须为0
              distanceToLabelLine: 0, //圆点到labelline距离
              borderRadius: 2.5,
              padding: [2.5, -2.5, 2.5, -2.5],
              /*radius和padding为圆点大小，圆点半径为几radius和padding各项数值就为几
                如：圆点半径为1
                          borderRadius: 1,
                          padding: [1, -1, 1, -1]
              */
              formatter: '{a|{b}：}{b|{d}%}',
              rich: {
                a: {
                  padding: [0, 0, 0, 10]
                },
                b: {
                  padding: [0, 10, 0, 0]
                }
              }
            },
            data: ciecle
          },

        ]
      }
      /**饼状图（环状）*/
      if (graphicalCss == 'pie-ring') {
        let ciecle = x.map((item, index) => {
          let obj = {
            name: item,
            value: y[0][index]
          }
          return obj
        })
        option = {
          title: {
            text: `{a|${title}}`,
            textStyle: {
              rich: {
                a: {
                  fontWeight: 'bold',
                  fontSize: '20',
                },
              }
            },
            left: 'center',
          },
          tooltip: {
            trigger: 'axis',
            axisPointer: {
              type: 'shadow'
            }
          },
        }
        option.series = [
          {
            type: 'pie',
            center: ['50%', '50%'],
            radius: ['30%', '50%'],
            minAngle: 10,
            avoidLabelOverlap: true,
            hoverOffset: 15,
            itemStyle: {
              borderColor: '#fff',
              borderWidth: 4,
              color: (params) => {
                return colors[params.dataIndex % colors.length]
              }
            },
            label: {
              show: true,
              position: 'outer',
              alignTo: 'labelLine',
              // ·圆点
              backgroundColor: 'auto', //圆点颜色，auto：映射的系列色
              height: 0,
              width: 0,
              lineHeight: 0,
              // height,width.lineHeight必须为0
              distanceToLabelLine: 0, //圆点到labelline距离
              borderRadius: 2.5,
              padding: [2.5, -2.5, 2.5, -2.5],
              /*radius和padding为圆点大小，圆点半径为几radius和padding各项数值就为几
                如：圆点半径为1
                          borderRadius: 1,
                          padding: [1, -1, 1, -1]
              */
              formatter: '{a|{b}：}{b|{d}%}',
              rich: {
                a: {
                  padding: [0, 0, 0, 10]
                },
                b: {
                  padding: [0, 10, 0, 0]
                }
              }
            },
            data: ciecle
          },

        ]
      }
      /**散点图*/
      if (graphicalCss == 'scatter-basic') {
        option.tooltip = {
          trigger: 'axis',
          backgroundColor: 'rgba(0,15,78,0.6)',
          borderColor: '#00afff',
          borderWidth: 1,
          borderRadius: 0,
          textStyle: {
            color: "#fff",
            fontSize: 13,
            align: 'left'
          },
          axisPointer: {
            type: 'line',
            lineStyle: {
              width: 1,
              type: 'dotted',
              color: 'rgba(46,149,230,.9)'
            }
          }
        }
        option.series = y.map((item, index) => {
          let a = 0
          var sum = 0;
          for (var i = 0; i < item.length; i++) {
            console.log(item[i])
            sum += Number(item[i]);
          }
          a = sum / item.length;
          let obj = {
            z: index,
            name: yData[index].name,
            type: 'effectScatter',
            itemStyle: {
              normal: {
                color: colors[index]
              }
            },
            symbol: 'circle', //circle, rect, roundRect, triangle,  pin, diamond, arrow
            symbolPosition: 'end',
            // symbolSize: 80,
            symbolOffset: [0, '-120%'],
            data: item.map(res => {
              let obj = {
                value: res,
                symbolSize: (res / a) * 10
              }
              return obj
            })
          }
          return obj
        })
      }
      /**面积图*/
      if (graphicalCss == 'area-basic') {
        const hexToRgba = (hex, opacity) => {
          let rgbaColor = "";
          let reg = /^#[\da-f]{6}$/i;
          if (reg.test(hex)) {
            rgbaColor = `rgba(${parseInt("0x" + hex.slice(1, 3))},${parseInt(
              "0x" + hex.slice(3, 5)
            )},${parseInt("0x" + hex.slice(5, 7))},${opacity})`;
          }
          return rgbaColor;
        }
        option.series = y.map((item, index) => {
          let obj = {
            z: index,
            name: yData[index].name,
            type: 'line',
            smooth: true,
            symbol: 'circle',
            clip: true,
            itemStyle: {
              normal: {
                color: colors[index]
              }
            },
            areaStyle: {
              normal: {
                color: new echarts.graphic.LinearGradient(
                  0,
                  0,
                  0,
                  1,
                  [{
                    offset: 0,
                    color: hexToRgba(colors[index], 1)
                  },
                  {
                    offset: 1,
                    color: hexToRgba(colors[index], 0.5)
                  }
                  ],
                  false
                ),
                shadowColor: hexToRgba(colors[index], 0.1),
                shadowBlur: 10
              }
            },
            data: item
          }
          return obj
        })
        option.tooltip.axisPointer = {
          type: 'line',
          lineStyle: {
            width: 1,
            type: 'dotted',
            color: 'rgba(46,149,230,.9)'
          }
        }
      }
      /**组合图(簇状柱)*/
      if (graphicalCss == 'constitution-basic') {
        y.forEach((item, index) => {
          let obj1 = {
            z: index,
            name: yData[index].name,
            type: 'bar',
            barMaxWidth: '40',
            barMinWidth: '20',
            barGap: '8%',
            barCategoryGap: '20%',
            itemStyle: {
              normal: {
                color: colors[index],
                opacity: 0.5
              }
            },
            data: item
          }
          let obj2 = {
            z: index + yData.length + 10,
            name: yData[index].name,
            type: 'line',
            symbol: 'circle',
            itemStyle: {
              normal: {
                color: colors[index],
              }
            },
            data: item
          }
          option.series.push(obj1)
          option.series.push(obj2)

        })
        option.tooltip.axisPointer = {
          type: 'line',
          lineStyle: {
            width: 1,
            type: 'dotted',
            color: 'rgba(46,149,230,.9)'
          }
        }
      }

      return option

    },
  }
}
</script>
<style lang="scss" scoped>
.echarts {
  width: 100%;
  height: 100%;
  border: 1px solid #cccccc;
  padding: 10px;
  #echarts {
    width: 100%;
    height: 100%;
  }
}
</style>


